package com.softao.ming.gde.internal.core.launcher.tasks;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipFile;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import com.softao.ming.gde.core.BundleRegistry;
import com.softao.ming.gde.core.launcher.LauncherContext;
import com.softao.ming.gde.core.launcher.LauncherSettings;
import com.softao.ming.gde.core.model.IBundleModel;
import com.softao.ming.gde.internal.core.ant.AntScript;
import com.softao.ming.gde.internal.core.ant.FileSet;
import com.softao.ming.gde.internal.core.natures.GdePluginFile;
import com.softao.ming.gde.internal.core.util.LaunchUtil;

/**
 * 
 */
public class CreateAntBuildTask extends AbstractLauncherTask {

	@Override
	public void perform(LauncherContext context, IProgressMonitor monitor)
			throws CoreException {
		monitor.subTask("Generating the ant file...");
		
		generate(context);
		
		monitor.worked(1);
	}

	private void generate(LauncherContext context) {
		LauncherSettings settings = context.getSettings();
		
		File antFile = new File(settings.getOutputLocation(), "build.xml");
		try {
			FileOutputStream antFileOutputStream = new FileOutputStream(antFile);
			printAntFile(antFileOutputStream, context);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@SuppressWarnings("unchecked")
	private List getClassPath(LauncherContext context) {
		BundleRegistry bundleRegistry = context.getBundleRegistry();
		
		List<String> result = new ArrayList<String>();
		for (IBundleModel plugin : bundleRegistry.allSourceBundles()) {
			File file = plugin.getContainerFile();
			
			if (file.isFile()) {
				try {
					ZipFile zipFile = new ZipFile(file, ZipFile.OPEN_READ);
					if (zipFile.getEntry(GdePluginFile.FILE_NAME) != null) {
						result.add(file.getPath());
					}
					zipFile.close();
				} catch (IOException e) {
					e.printStackTrace();
					continue;
				}
				
			} else {
				File gwtPluginFile = new File(file, GdePluginFile.FILE_NAME);
				if (!gwtPluginFile.exists()) {
					continue;
				}
				result.add(file.getPath());
				
				File buildFile = new File(file, "build.properties");
				if (!buildFile.exists()) {
					continue;
				}
				
				String[] sourceFolders;
				try {
					InputStream buildEntryStream = new FileInputStream(buildFile);
					sourceFolders = LaunchUtil.getSourceFolders(buildEntryStream);
					buildEntryStream.close();
					
					if (sourceFolders.length == 0) {
						continue;
					}
				} catch (IOException e) {
					e.printStackTrace();
					continue;
				}

				for (String sourceFolder : sourceFolders) {
					File sourceFile = new File(file, sourceFolder);
					result.add(sourceFile.getPath());
				}
			}
		}
		
		String gwtLocation = context.getSettings().getGwtInstallationLocation();
		File gwtFile = new File(gwtLocation);
		result.add((new File(gwtFile, "gwt-dev-windows.jar")).getPath());
		result.add((new File(gwtFile, "gwt-servlet.jar")).getPath());
		result.add((new File(gwtFile, "gwt-user.jar")).getPath());
		
		result.add(context.getSettings().getOutputLocation() + "\\src");
		return result;
	}
	
	@SuppressWarnings({"unchecked" })
	private void printAntFile(FileOutputStream antFileOutputStream, LauncherContext context) throws IOException {
		LauncherSettings settings = context.getSettings();
		
		final String gwtEntryModule = "com.softao.ming.gwt.bootstrap.MingBootstrap";
		
		List classPath = getClassPath(context);
		AntScript antScript = new AntScript(antFileOutputStream);
		antScript.printProjectDeclaration("test", "build", settings.getOutputLocation());
		antScript.printPathStructure("path", "build.classpath", classPath);
		
		antScript.printTargetDeclaration("compile", null, null, null, null);
		
		printGwtBuildTask(antScript, gwtEntryModule, "build.classpath");
		
		antScript.printEndTag("target");
		
		antScript.printTargetDeclaration("copy-config", null, null, null, null);
		for (String configPath : settings.getConfigurationLocations()) {
			if (configPath != null && configPath.trim().length() > 0) {
				antScript.printCopyTask(null, 
						settings.getOutputLocation() + "/war/WEB-INF/classes/", 
						new FileSet[] {new FileSet(configPath, null, "*.*", null, null, null, null)}, true, true);
			}
		}
		antScript.printEndTag("target");

		antScript.printTargetDeclaration("build", "compile, copy-config", null, null, null);
		antScript.printEndTag("target");
		
		antScript.printEndTag("project");
		antScript.close();
	}
	
	private void printGwtBuildTask(AntScript script, String entryClass, String classPathId) {
		script.printTab();
		script.printTab();
		script.print("<java");
		
		script.printAttribute("classname", "com.google.gwt.dev.Compiler", true);
		//script.printAttribute("classname", "com.google.gwt.dev.GWTCompiler", true);
		script.printAttribute("fork", "true", true);
		script.println(">");
		/*
		script.printTabs();
		script.print("<arg");
		script.printAttribute("value", "-out", true);
		script.println("/>");
		script.printTabs();
		script.print("<arg");
		script.printAttribute("value", mOutputLocation, true);
		script.println("/>");
		script.printTabs();
		script.print("<arg");
		script.printAttribute("value", "%*", true);
		script.println("/>");
		*/
		script.printTabs();
		script.print("<jvmarg");
		script.printAttribute("value", "-Xmx512M", true);
		script.println("/>");
		
		script.printTabs();
		script.print("<arg");
		script.printAttribute("value", entryClass, true);
		script.println("/>");
		
		script.printTabs();
		script.print("<classpath");
		script.printAttribute("refid", classPathId, true);
		script.println("/>");
		
		script.println("</java>");
	}

}
